package com.softWang.common.filter;

import com.softWang.common.base.LoginUser;
import com.softWang.common.constants.CacheKeys;
import com.softWang.common.service.CacheService;
import com.softWang.common.tenent.context.TenantContextHolder;
import com.softWang.common.utils.IPUtils;
import com.softWang.common.utils.SecurityUtils;
import com.softWang.common.utils.WebUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Token 过滤器，验证 token 的有效性
 * 验证通过后，获得 {@link LoginUser} 信息，并加入到 Spring Security 上下文

 */
@Component
@RequiredArgsConstructor
public class TokenAuthenticationFilter extends OncePerRequestFilter {

    @Value("${token.header}")
    private String tokenHeader;

    @Resource
    private CacheService cacheService;

    @Override
    @SuppressWarnings("NullableProblems")
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        String accessToken = WebUtils.getHeader(request,tokenHeader);
        if (accessToken == null || accessToken.isEmpty()) {
            // 未携带 token，查询queryParams
            accessToken = request.getParameter(tokenHeader);
        }
        if (accessToken!= null && !accessToken.isEmpty()) {
            Object userIdObj = cacheService.getCacheObject(CacheKeys.LOGIN_ACCESS_TOKEN_PREFIX + accessToken);
            if (userIdObj != null) {
                Long userId = Long.valueOf(userIdObj.toString());
                LoginUser loginUser = cacheService.getCacheObject(CacheKeys.LOGIN_USER_PREFIX + userId);
                if(loginUser != null){
                    loginUser.setUserIp(IPUtils.getIpAddr(request));
                    SecurityUtils.setLoginUser(loginUser,request);
                    TenantContextHolder.setTenantId(loginUser.getTenantId());
                }
            }
        }

        // 继续过滤链
        chain.doFilter(request, response);
    }

}
